home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
076-100
/
disk_092
/
as6502
/
assm1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
10KB
|
437 lines
/* As6502 main routine: assm1.c */
#include "stdio.h"
#include "ctype.h"
#include "assm.d1"
#include "assm.d2"
#include <time.h>
#define CPMEOF EOF
/* Version 5.0 ported to the Amiga 3/1/87 by Joel Swank */
/* Version 5.0 is a major revision by Joel Swank. It adds the following
* features: '.PAGE' pseudo with optional title; automatic paging and
* -p flag to specify page length; A sorted symbol cross reference;
* -t flag to specify the symbol table size; -w flag to specify the width
* of a listing line. The -m option causes the object file to be formatted
* as a standard MOS Technology object file. Also added error checking
* and error messages to the argument parsing routine.
*/
/*
* Two changes to version 1.4 have been made to "port" as6502 to CP/M(tm).
* A "tolower()" function call was add to the command line processing
* code to (re)map the command line arguments to lower case (CP/M
* converts all command line arguments to upper case). The readline()
* function has code added to "ignore" the '\r' character (CP/M includes
* the \r character along with \n).
*
* Also, the ability to process multiple files on the command line has been
* added. Now one can do, for example:
*
* as6502 -nisvo header.file source.file data.file ...
*
* George V. Wilder
* IX 1A-360 x1937
* ihuxp!gvw1
*/
/* Had to take out tolower call to work on 4.2bsd. Joel Swank 5/9/85 */
/* Added USAGE message in place of Invalid count message JS 12/2/86 */
int badflag;
int act;
char **avt;
main(argc, argv)
int argc;
char *argv[];
{
char *malloc();
int cnt;
int i;
int ac;
char **av;
long l;
size = STABSZ;
pagesize = PAGESIZE;
linesize = LINESIZE;
getargs(argc, argv); /* parse the command line arguments */
if (badflag > 0) exit(1);
if (act == 0) {
fprintf(stderr, "USAGE: as6502 -[milnosv] [-p -t -w] file ...\n");
exit(1);
}
symtab = malloc(size);
if (symtab == 0) {
fprintf(stderr,"Symbol table allocation failed - specify a smaller size\n");
exit(2); }
time(&l);
date = ctime(&l);
date[24] = '\0';
pagect = 0;
paglin = pagesize;
titlesize = linesize-36;
for (i=0 ; i<100; i++) titlbuf[i] = ' ';
titlbuf[titlesize] = '\0';
for (i=0 ; i<linesize-58; i++) syspc[i] = ' ';
syspc[i] = '\0';
ac = act;
av = avt;
pass = FIRST_PASS;
errcnt = loccnt = slnum = 0;
fprintf(stderr,"Initialization complete\n");
while (pass != DONE) {
initialize(ac, av, act);
fprintf(stderr,"PASS %d %s\n",pass+1,*av);
if(pass == LAST_PASS && ac == act)
errcnt = loccnt = slnum = 0;
/* lower level routines can terminate assembly by setting
pass = DONE ('symbol table full' does this) */
while (readline() != -1 && pass != DONE)
assemble(); /* rest of assembler executes from here */
if (errcnt != 0) {
pass = DONE;
fprintf(stderr, "Terminated with error counter = %d\n", errcnt);
}
switch (pass) {
case FIRST_PASS:
--ac;
++av;
if(ac == 0) {
pass = LAST_PASS;
if (lflag == 0)
lflag++;
ac = act;
av = avt;
}
break;
case LAST_PASS:
--ac;
++av;
if(ac == 0) {
pass = DONE;
if (sflag != 0)
stprnt();
}
}
wrapup();
if ((dflag != 0) && (pass == LAST_PASS)) {
fprintf(stdout, "nxt_free = %d\n", nxt_free);
cnt = 0;
}
}
fclose(stdout);
free(symtab);
return(0);
}
/*****************************************************************************/
/* parse the command args and save data */
getargs(argc,argv)
int argc;
char *argv[];
{
int i;
char c;
int sz;
while (--argc > 0 && (*++argv)[0] == '-') {
for (i = 1; (c = (*argv)[i]) != '\0'; i++) {
switch (c) {
case 'd': /* debug flag */
dflag++;
break;
case 'i': /* ignore .nlst flag */
iflag++;
break;
case 'l': /* disable listing flag */
lflag--;
break;
case 'n': /* normal/split address mode */
nflag++;
break;
case 'o': /* object output flag */
oflag++;
break;
case 'm': /* MOS Tech. object format */
mflag++;
oflag++; /* -m implies -o */
break;
case 's': /* list symbol table flag */
sflag++;
break;
case 'v': /* print assembler version */
fprintf(stderr,
"as6502 - Amiga version 5.0 - 3/1/87 - JHV [gvw,jhs]\n");
break;
case 't': /* input symbol table size */
{
if ((*argv)[++i] == '\0') {
++argv;
argc--;
sz = atoi(*argv);
} else sz = atoi(&(*argv)[i]);
if (sz>1000) size=sz;
else {
fprintf(stderr,
"Invalid Symbol table size - minimum is 1000\n");
badflag++; }
goto outofloop;
}
case 'p': /* input lines per page */
{
if ((*argv)[++i] == '\0') {
++argv;
argc--;
sz = atoi(*argv);
} else sz = atoi(&(*argv)[i]);
if (sz>10 || sz == 0) pagesize=sz;
else {
fprintf(stderr,
"Invalid Pagesize - minimum is 10\n");
badflag++; }
goto outofloop;
}
case 'w': /* input characters per line */
{
if ((*argv)[++i] == '\0') {
++argv;
argc--;
sz = atoi(*argv);
} else sz = atoi(&(*argv)[i]);
if (sz >= 80 && sz < 133) linesize=sz;
else {
fprintf(stderr,
"Invalid Linesize - min is 80, max is 133\n");
badflag++; }
goto outofloop;
}
default:
fprintf(stderr,"Unknown flag '%c'\n",c);
badflag++;
} /* end switch */
} /* end for */
outofloop: ;
}
act=argc; /* return values to main */
avt=argv;
}
/*****************************************************************************/
/* initialize opens files */
initialize(ac, av, argc)
int ac;
char *av[];
int argc;
{
if ((iptr = fopen(*av, "r")) == NULL) {
fprintf(stderr, "Open error for file '%s'.\n", *av);
exit(1);
}
if ((pass == LAST_PASS) && (oflag != 0) && ac == argc) {
if ((optr = fopen("6502.out", "w")) == NULL) {
fprintf(stderr, "Create error for object file 6502.out.\n");
exit(1);
}
}
}
/* readline reads and formats an input line */
int field[] =
{
SFIELD,
SFIELD + 8,
SFIELD + 14,
SFIELD + 23,
SFIELD + 43,
SFIELD + 75
};
readline()
{
int i; /* pointer into prlnbuf */
int j; /* pointer to current field start */
int ch; /* current character */
int cmnt; /* comment line flag */
int spcnt; /* consecutive space counter */
int string; /* ASCII string flag */
int temp1; /* temp used for line number conversion */
temp1 = ++slnum;
clrlin();
i = 3;
while (temp1 != 0) { /* put source line number into prlnbuf */
prlnbuf[i--] = temp1 % 10 + '0';
temp1 /= 10;
}
i = SFIELD;
cmnt = spcnt = string = 0;
j = 1;
while ((ch = getc(iptr)) != '\n') {
if(ch == '\r')
continue;
prlnbuf[i++] = ch;
if ((ch == ' ') && (string == 0)) {
if (spcnt != 0)
--i;
else if (cmnt == 0) {
++spcnt;
if (i < field[j])
i = field[j];
if (++j > 3) {
spcnt = 0;
++cmnt;
}
}
}
else if (ch == '\t') {
prlnbuf[i - 1] = ' ';
spcnt = 0;
if (cmnt == 0) {
if (i < field[j])
i = field[j];
if (++j > 3)
++cmnt;
}
else i = (i + 8) & 0x78;
}
else if ((ch == ';') && (string == 0)) {
spcnt = 0;
if (i == SFIELD + 1)
++cmnt;
else if (prlnbuf[i - 2] != '\'') {
++cmnt;
prlnbuf[i-1] = ' ';
if (i < field[3])
i = field[3];
prlnbuf[i++] = ';';
}
}
else if (ch == EOF || ch == CPMEOF)
return(-1);
else {
if ((ch == '"') && (cmnt == 0))
string = string ^ 1;
spcnt = 0;
if (i >= LAST_CH_POS - 1)
--i;
}
}
prlnbuf[i] = 0;
return(0);
}
/*
* wrapup() closes the source, object and stdout files
*/
wrapup()
{
fclose(iptr); /* close source file */
if (pass == DONE) {
if ((oflag != 0) && (optr !=0)) {
if (mflag != 0) fin_obj();
else fputc('\n', optr);
fclose(optr);
}
}
return;
}
/* symbol table print
*/
stprnt()
{
int i; /* print line position */
int ptr; /* symbol table position */
int j; /* integer conversion variable */
int k; /* printf buffer pointer */
int refct; /* counter for references */
char buf[6];
paglin = pagesize;
ptr = 0;
clrlin();
while (ptr < nxt_free)
{
for (i=1; i <= symtab[ptr]; i++) prlnbuf[i] = symtab[ptr+i];
ptr += i+1; i=23; /* value at pos 23 */
j = symtab[ptr++] & 0xff;
j += (symtab[ptr++] << 8);
hexcon(4,j);
if (nflag == 0) {
i--;
prlnbuf[i++] = hex[3];
prlnbuf[i++] = hex[4];
prlnbuf[i++] = ':';
prlnbuf[i++] = hex[1];
prlnbuf[i++] = hex[2]; }
else for (k=1; k<5; k++) prlnbuf[i++] = hex[k];
j = symtab[ptr++] & 0xff;
j += (symtab[ptr++] << 8);
sprintf(buf,"%d",j);
k=0;i=30; /* line defined at pos 30 */
while (buf[k] != '\0') prlnbuf[i++] = buf[k++];
k=0;i=37; /* count of references */
refct = symtab[ptr++] & 0xff;
sprintf(buf,"(%d)",refct);
while (buf[k] != '\0') prlnbuf[i++] = buf[k++];
i++; /* and all the references */
while (refct > 0)
{
j = symtab[ptr++] & 0xff;
j += (symtab[ptr++] << 8);
sprintf(buf,"%d",j);
k=0;
while (buf[k] != '\0') prlnbuf[i++] = buf[k++];
i++;
refct--;
if ( i > linesize-5 && refct > 0) {
prlnbuf[i] = '\0';
prsyline(); i=37; }
}
prlnbuf[i] = '\0';
prsyline();
}
}
/* prsyline prints the contents of prlnbuf */
prsyline()
{
if (paglin == pagesize) prsymhead();
prlnbuf[linesize] = '\0';
fprintf(stdout, "%s\n", prlnbuf);
paglin++ ;
clrlin();
}
/****************************************************************************/
/* prsymhead prints the page heading */
prsymhead()
{
if (pagesize == 0) return;
pagect++ ;
fprintf(stdout, "\f\nAmiga 6502 assembler : Symbol Cross Reference - %s PAGE %d\n",syspc,pagect);
fprintf(stdout, "Symbol Value Defined References\n\n");
paglin = 0;
}
/* clear the print buffer */
clrlin()
{
int i;
for (i = 0; i < LAST_CH_POS; i++)
prlnbuf[i] = ' ';
}